package daily_exercise;

// 懒汉
class Singleton1{
    private Singleton1 instance = null;

    private Singleton1(){
        System.out.println(Thread.currentThread() + " :我是构造方法Singleton1()");
    }

    public Singleton1 getInstance(){
        if (instance == null){
            instance = new Singleton1();
        }
        return instance;
    }

    public static void main(String[] args) {
        Singleton1 singleton1 = new Singleton1();
        for (int i = 0; i < 10; i++) {
            new Thread(()->{singleton1.getInstance();}, String.valueOf(i)).start();
        }
    }
}

// 懒汉DCL
class Singleton3{
    // 加volatile是因为：多线程时的指令重排可能影响结果
    // 比如当一个线程访问instance不为空时，由于instance示例未必初始化完成（指令重排），
    // 获取到的是一个错误的结果
    private volatile Singleton3 instance = null;

    private Singleton3(){
        System.out.println(Thread.currentThread() + " :我是构造方法Singleton1()");
    }

    public Singleton3 getInstance(){
        if (instance == null){
            synchronized (Singleton3.class){
                // 再检查一遍是因为instance的引用对象之前可能没有完成初始化
                if (instance == null){
                    instance = new Singleton3();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        Singleton3 singleton = new Singleton3();
        for (int i = 0; i < 10; i++) {
            new Thread(()->{singleton.getInstance();}, String.valueOf(i)).start();
        }
    }
}


// 饿汉
class Singleton2{
    private static final Singleton2 instance = new Singleton2();

    private Singleton2(){
        System.out.println(Thread.currentThread() + " :我是构造方法Singleton2()");
    }

    public Singleton2 getInstance(){
        return instance;
    }

    public static void main(String[] args) {
        Singleton2 singleton2 = new Singleton2();
        for (int i = 0; i < 10; i++) {
            new Thread(()->{singleton2.getInstance();}, String.valueOf(i)).start();
        }
    }
}

public class singletonDemo {
    public static void main(String[] args) {

    }
}
